/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2010 huliqing, huliqing.cn@gmail.com
 *
 * This file is part of QFaces.
 * QFaces is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * QFaces is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with QFaces.  If not, see <http://www.gnu.org/licenses/>.
 *
 * 这个文件是QFaces的一部分。
 * 您可以单独使用或分发这个文件，但请不要移除这个头部声明信息.
 * QFaces是一个自由软件，您可以自由分发、修改其中的源代码或者重新发布它，
 * 新的任何修改后的重新发布版必须同样在遵守LGPL3或更后续的版本协议下发布.
 * 关于LGPL协议的细则请参考COPYING、COPYING.LESSER文件，
 * 您可以在QFaces的相关目录中获得LGPL协议的副本，
 * 如果没有找到，请连接到 http://www.gnu.org/licenses/ 查看并获取副本。
 *
 * - Author: Huliqing
 * - Contact: huliqing.cn@gmail.com
 * - License: GNU Lesser General Public License (LGPL)
 * - Blog and source code availability: http://www.huliqing.name/
 */

package name.huliqing.qfaces.component;

//import java.util.logging.Logger;

import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;

import name.huliqing.qfaces.QFaces;

public class Frame extends UIComponentBase implements java.io.Serializable{
//	private final static Logger logger = Logger.getLogger(Frame.class.getName());
	
    public enum CssPosition {
        /** static */
        STATIC,
        
        /** absolute */
        ABSOLUTE,
        
        /** fixed */
        FIXED,
        
        /** relative */
        RELATIVE;
    }
    
    // Frame,窗口的id,通过这个ID，可以获得这个窗口的实例，
    // 并以此来控制窗口的显示，关闭，移动等。。
    private String frameId;
    
    // Frame,窗口包含labelHeader的容器(如div) id
    private String headerId;
    
    // Frame,窗口中close按钮的id
    private String closeId;
    
    // Frame,header的标签描述
    private String labelHeader;
    
    // Frame,指定了窗口在客户端是否为可见的
    private Boolean visible;
    
    // Frame,指定窗口是否可以拖动的
    private Boolean drag;
    
    // Frame,指定是否渲染窗口的边框
    private Boolean renderBorder;
    
    // Frame,指定是否渲染窗口的close按钮
    private Boolean renderCloseButton;
    
    // Frame,指定窗口的header的css样式类
    private String styleClassHeader;
    
    // Frame,指定窗口的css位置属性,取值只能是
    // : absolute, fixed,relative,static中之一，默认为：static
    private String cssPosition; // absolute,fixed,relative,static
    
    // Frame,指定窗口的皮肤样式
    private String face;
    
    // 手动保存RendererType:在其它组件内部生成Frame时(编程方式生成Frame),
    // Frame需要随着父组件进行状态保存，但是默认的Frame rendererType
    // 可能无法保存状，这会导致回传时Frame组件不会,所以需要手动保存状态
    private String rendererType;
    
    // 组件在客户端中的x位置
    private Integer clientX;
    
    // 组件在客户端中的y位置
    private Integer clientY;
    
    private String loadType;

    public Frame() {
    	super();
    	setRendererType("name.huliqing.qfaces.render.FrameRenderer");
    }

    @Override
	public void setRendererType(String rendererType) {
		this.rendererType = rendererType;
	}

	@Override
	public String getRendererType() {
    	return this.rendererType;
	}

	@Override
	public String getFamily() {
		return "name.huliqing.qfaces.render.FrameFamily";
	}
    
    private Object[] _values;
    
    @Override
	public void restoreState(FacesContext fc, Object state) {
    	_values = (Object[]) state;
		super.restoreState(fc, _values[0]);
		this.frameId = (String) _values[1];
		this.headerId = (String) _values[2];
		this.closeId = (String) _values[3];
		this.labelHeader = (String) _values[4];
		this.visible = (Boolean) _values[5];
		this.drag = (Boolean) _values[6];
		this.renderBorder = (Boolean) _values[7];
		this.renderCloseButton = (Boolean) _values[8];
		this.styleClassHeader = (String) _values[9];
		this.cssPosition = (String) _values[10];
		this.face = (String) _values[11];
		this.rendererType = (String) _values[12];
		this.clientX = (Integer) _values[13];
		this.clientY = (Integer) _values[14];
		this.loadType = (String) _values[15];
	}

	@Override
	public Object saveState(FacesContext fc) {
		if (_values == null) 
			_values = new Object[16];
		_values[0] = super.saveState(fc);
		_values[1] = this.frameId;
		_values[2] = this.headerId;
		_values[3] = this.closeId;
		_values[4] = this.labelHeader;
		_values[5] = this.visible;
		_values[6] = this.drag;
		_values[7] = this.renderBorder;
		_values[8] = this.renderCloseButton;
		_values[9] = this.styleClassHeader;
		_values[10] = this.cssPosition;
		_values[11] = this.face;
		_values[12] = this.rendererType;
		_values[13] = this.clientX;
		_values[14] = this.clientY;
		_values[15] = this.loadType;
		return _values;
	}
	
	/**
	 * 从目标组件中载入参数,这个方法主要用于与其它组件的配合.
	 * 在动态生成Frame时可能需要从目标组件中载入必要的参数以
	 * 置换Frame中的默认参数
	 * @param ui
	 */
	public void loadAttributeFrom(UIComponent ui) {
		this.frameId = (String) ui.getAttributes().get("frameId");
		this.headerId = (String) ui.getAttributes().get("headerId");
		this.closeId = (String) ui.getAttributes().get("closeId");
		this.labelHeader = (String) ui.getAttributes().get("labelHeader");
		this.visible = QFaces.convertToBoolean(ui.getAttributes().get("visible"));
		this.drag = QFaces.convertToBoolean(ui.getAttributes().get("drag"));
		this.renderBorder = QFaces.convertToBoolean(ui.getAttributes().get("renderBorder"));
		this.renderCloseButton = QFaces.convertToBoolean(ui.getAttributes().get("renderCloseButton"));
		this.styleClassHeader = (String) ui.getAttributes().get("styleClassHeader");
		this.cssPosition = (String) ui.getAttributes().get("cssPosition");
		this.face = (String) ui.getAttributes().get("face");
		this.loadType = (String) ui.getAttributes().get("loadType");
	}

    // ---- Getter and Setter
	
	private Object getFromExp(String name) {
		ValueExpression _ve = getValueExpression(name);
        if (_ve != null)
            return _ve.getValue(getFacesContext().getELContext());
        else
            return null;
	}

    /**
     * 获取FrameId，frameId可用于控制窗口的打开或关闭,
     * 如，在客户端可通过JavaScript来控制:Q.U.open(frameId)来打开窗口
     * @return frameId
     */
    public String getFrameId() {
    	if (frameId != null)
    		return frameId;
    	return (String) getFromExp("frameId");
    }

    public void setFrameId(String frameId) {
        this.frameId = frameId;
    }

    public String getHeaderId() {
    	if (headerId != null)
    		return headerId;
    	return (String) getFromExp("headerId");
    }

    public void setHeaderId(String headerId) {
        this.headerId = headerId;
    }

    public String getCloseId() {
    	if (closeId != null)
    		return closeId;
    	return (String) getFromExp("closeId");
    }

    public void setCloseId(String closeId) {
        this.closeId = closeId;
    }

    /**
     * 获取Header的标签描述
     * @return labelHeader
     */
    public String getLabelHeader() {
    	if (labelHeader != null)
    		return labelHeader;
    	return (String) getFromExp("labelHeader");
    }

    /**
     * 设置Header的标签描述
     * @param labelHeader
     */
    public void setLabelHeader(String labelHeader) {
        this.labelHeader = labelHeader;
    }

    /**
     * 获取Header的css样式类
     * @return styleClassHeader
     */
    public String getStyleClassHeader() {
    	if (styleClassHeader != null)
    		return styleClassHeader;
    	return (String) getFromExp("styleClassHeader");
    }

    /**
     * 设置Header的css样式类
     * @param styleClassHeader
     */
    public void setStyleClassHeader(String styleClassHeader) {
        this.styleClassHeader = styleClassHeader;
    }

    /**
     * 获取使用的皮肤样式
     * @return face
     */
    public String getFace() {
    	if (face != null)
    		return face;
    	return (String) getFromExp("face");
    }

    /**
     * 设置使用的皮肤样式
     * @param face
     */
    public void setFace(String face) {
        this.face = face;
    }

    /**
     * 获取是否渲染Frame的边框
     * @return renderBorder
     */
    public Boolean getRenderBorder() {
    	if (renderBorder != null)
    		return renderBorder;
    	return (Boolean) getFromExp("renderBorder");
    }

    /**
     * 设置是否渲染Frame的边框
     * @param renderBorder
     */
    public void setRenderBorder(Boolean renderBorder) {
        this.renderBorder = renderBorder;
    }

    /**
     * 获取是否允许Frame的拖动功能
     * @return drag
     */
    public Boolean getDrag() {
    	if (drag != null)
    		return drag;
    	return (Boolean) getFromExp("drag");
    }

    /**
     * 设置Frame是否允许被拖动
     * @param drag
     */
    public void setDrag(Boolean drag) {
        this.drag = drag;
    }

    /**
     * 获取是否渲染Frame的“关闭”按钮
     * @return renderCloseButton
     */
    public Boolean getRenderCloseButton() {
    	if (renderCloseButton != null)
    		return renderCloseButton;
    	return (Boolean) getFromExp("renderCloseButton");
    }

    /**
     * 设置是否渲染Frame的“关闭”按钮
     * @param renderCloseButton
     */
    public void setRenderCloseButton(Boolean renderCloseButton) {
        this.renderCloseButton = renderCloseButton;
    }

    /**
     * 获取Frame在客户端是否为可见的。
     * @return visible
     */
    public Boolean getVisible() {
    	if (visible != null)
    		return visible;
    	return (Boolean) getFromExp("visible");
    }

    /**
     * 设置Frame在客户端是否为可见的。
     * @param visible
     */
    public void setVisible(Boolean visible) {
        this.visible = visible;
    }

    /**
     * 获取frame的css属性position
     * @return cssPosition
     */
    public String getCssPosition() {
    	if (cssPosition != null) 
    		return cssPosition;
    	return (String) getFromExp("cssPosition");
    }

    /**
     * 设置Frame的css属性position
     */
    public void setCssPosition(String cssPosition) {
        this.cssPosition = cssPosition;
    }

	public Integer getClientX() {
		if (clientX != null)
			return clientX;
		return (Integer) getFromExp("clientX");
	}

	public void setClientX(Integer clientX) {
		this.clientX = clientX;
	}

	public Integer getClientY() {
		if (clientY != null)
			return clientY;
		return (Integer) getFromExp("clientY");
	}

	public void setClientY(Integer clientY) {
		this.clientY = clientY;
	}
	
	public String getLoadType() {
		if (loadType != null)
			return loadType;
		return (String) this.getFromExp("loadType");
	}
	
	public void setLoadType(String loadType) {
		this.loadType = loadType;
	}
}
